home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cdrtools-1.10 / cdrecord / drv_jvc.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-30  |  37.4 KB  |  1,492 lines

  1. /** @(#)drv_jvc.c    1.51 00/07/30 Copyright 1997 J. Schilling */
  2. #ifndef lint
  3. static    char sccsid[] =
  4.     "@(#)drv_jvc.c    1.51 00/07/30 Copyright 1997 J. Schilling";
  5. #endif
  6. /*
  7.  *    CDR device implementation for
  8.  *    JVC/TEAC
  9.  *
  10.  *    Copyright (c) 1997 J. Schilling
  11.  */
  12. /*
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2, or (at your option)
  16.  * any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; see the file COPYING.  If not, write to
  25.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27. /*#define    XXDEBUG*/
  28. /*#define    XXBUFFER*/
  29.  
  30. #include <mconfig.h>
  31.  
  32. #include <stdio.h>
  33. #include <standard.h>
  34. #include <fctldefs.h>
  35. #include <errno.h>
  36. #include <strdefs.h>
  37. #include <unixstd.h>
  38. #ifdef    XXDEBUG
  39. #include <stdxlib.h>
  40. #endif
  41.  
  42. #include <utypes.h>
  43. #include <btorder.h>
  44. #include <intcvt.h>
  45. #include <schily.h>
  46.  
  47. #include <scg/scgcmd.h>
  48. #include <scg/scsidefs.h>
  49. #include <scg/scsireg.h>
  50. #include <scg/scsitransp.h>
  51.  
  52. #include "cdrecord.h"
  53.  
  54. /* just a hack */
  55. long    lba_addr;
  56. BOOL    last_done;
  57.  
  58. /*
  59.  * macros for building MSF values from LBA
  60.  */
  61. #define LBA_MIN(x)    ((x)/(60*75))
  62. #define LBA_SEC(x)    (((x)%(60*75))/75)
  63. #define LBA_FRM(x)    ((x)%75)
  64. #define MSF_CONV(a)    ((((a)%100)/10)*16 + ((a)%10))
  65.  
  66. extern    int    lverbose;
  67.  
  68. #if defined(_BIT_FIELDS_LTOH)    /* Intel byteorder */
  69. struct teac_mode_page_21 {        /* teac dummy selection */
  70.         MP_P_CODE;        /* parsave & pagecode */
  71.     u_char    p_len;            /* 0x01 = 1 Byte */
  72.     Ucbit    dummy        : 2;
  73.     Ucbit    res        : 6;
  74. };
  75. #else
  76. struct teac_mode_page_21 {        /* teac dummy selection */
  77.         MP_P_CODE;        /* parsave & pagecode */
  78.     u_char    p_len;            /* 0x01 = 1 Byte */
  79.     Ucbit    res        : 6;
  80.     Ucbit    dummy        : 2;
  81. };
  82. #endif
  83.  
  84. struct teac_mode_page_31 {        /* teac speed selection */
  85.         MP_P_CODE;        /* parsave & pagecode */
  86.     u_char    p_len;            /* 0x02 = 2 Byte */
  87.     u_char    speed;
  88.     u_char    res;
  89. };
  90.  
  91. struct cdd_52x_mode_data {
  92.     struct scsi_mode_header    header;
  93.     union cdd_pagex    {
  94.         struct teac_mode_page_21    teac_page21;
  95.         struct teac_mode_page_31    teac_page31;
  96.     } pagex;
  97. };
  98.  
  99. #if defined(_BIT_FIELDS_LTOH)    /* Intel byteorder */
  100.  
  101. struct pgm_subcode {        /* subcode for progam area */
  102.     u_char    subcode;
  103.     Ucbit    addr        : 4;
  104.     Ucbit    control        : 4;
  105.     u_char    track;
  106.     u_char    index;
  107. };
  108.  
  109. #else
  110.  
  111. struct pgm_subcode {        /* subcode for progam area */
  112.     u_char    subcode;
  113.     Ucbit    control        : 4;
  114.     Ucbit    addr        : 4;
  115.     u_char    track;
  116.     u_char    index;
  117. };
  118.  
  119. #endif
  120.  
  121. #define    set_pgm_subcode(sp, t, c, a, tr, idx)        (\
  122.             (sp)->subcode = (t),         \
  123.             (sp)->control = (c),         \
  124.             (sp)->addr = (a),         \
  125.             (sp)->track = MSF_CONV(tr),     \
  126.             (sp)->index = (idx))
  127.  
  128. #define    SC_P        1    /* Subcode defines pre-gap (Pause)    */
  129. #define    SC_TR        0    /* Subcode defines track data        */
  130.  
  131. #if defined(_BIT_FIELDS_LTOH)    /* Intel byteorder */
  132.  
  133. typedef struct lin_subcode {    /* subcode for lead in area */
  134.     Ucbit    addr        : 4;
  135.     Ucbit    control        : 4;
  136.     u_char    track;
  137.     u_char    msf[3];
  138. } lsc_t;
  139.  
  140. #else
  141.  
  142. typedef struct lin_subcode {    /* subcode for lead in area */
  143.     Ucbit    control        : 4;
  144.     Ucbit    addr        : 4;
  145.     u_char    track;
  146.     u_char    msf[3];
  147. } lsc_t;
  148.  
  149. #endif
  150.  
  151. #define    set_toc_subcode(sp, c, a, tr, bno)                (\
  152.             ((lsc_t *)sp)->control = (c),             \
  153.             ((lsc_t *)sp)->addr = (a),             \
  154.             ((lsc_t *)sp)->track = MSF_CONV(tr),         \
  155.             ((lsc_t *)sp)->msf[0] = MSF_CONV(LBA_MIN(bno)),     \
  156.             ((lsc_t *)sp)->msf[1] = MSF_CONV(LBA_SEC(bno)),     \
  157.             ((lsc_t *)sp)->msf[2] = MSF_CONV(LBA_FRM(bno)),     \
  158.             &((lsc_t *)sp)->msf[3])
  159.  
  160. #define    set_lin_subcode(sp, c, a, pt, min, sec, frm)            (\
  161.             ((lsc_t *)sp)->control = (c),             \
  162.             ((lsc_t *)sp)->addr = (a),             \
  163.             ((lsc_t *)sp)->track = (pt),             \
  164.             ((lsc_t *)sp)->msf[0] = (min),             \
  165.             ((lsc_t *)sp)->msf[1] = (sec),             \
  166.             ((lsc_t *)sp)->msf[2] = (frm),             \
  167.             &((lsc_t *)sp)->msf[3])
  168.  
  169. #if defined(_BIT_FIELDS_LTOH)    /* Intel byteorder */
  170.  
  171. struct upc_subcode {        /* subcode for upc/bar code */
  172.     u_char    res;
  173.     Ucbit    addr        : 4;
  174.     Ucbit    control        : 4;
  175.     u_char    upc[13];
  176. };
  177.  
  178. #else
  179.  
  180. struct upc_subcode {        /* subcode for upc/bar code */
  181.     u_char    res;
  182.     Ucbit    control        : 4;
  183.     Ucbit    addr        : 4;
  184.     u_char    upc[13];
  185. };
  186.  
  187. #endif
  188.  
  189. #if defined(_BIT_FIELDS_LTOH)    /* Intel byteorder */
  190.  
  191. struct isrc_subcode {        /* subcode for ISRC code */
  192.     u_char    res;
  193.     Ucbit    addr        : 4;
  194.     Ucbit    control        : 4;
  195.     u_char    isrc[12];
  196.     u_char    res14;
  197. };
  198.  
  199. #else
  200.  
  201. struct isrc_subcode {        /* subcode for ISRC code */
  202.     u_char    res;
  203.     Ucbit    control        : 4;
  204.     Ucbit    addr        : 4;
  205.     u_char    isrc[12];
  206.     u_char    res14;
  207. };
  208.  
  209. #endif
  210.  
  211.  
  212. LOCAL    int    teac_attach        __PR((SCSI *scgp, cdr_t *dp));
  213. LOCAL    int    teac_getdisktype    __PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp));
  214. LOCAL    int    speed_select_teac    __PR((SCSI *scgp, int *speedp, int dummy));
  215. LOCAL    int    select_secsize_teac    __PR((SCSI *scgp, track_t *trackp));
  216. LOCAL    int    next_wr_addr_jvc    __PR((SCSI *scgp, int track, track_t *, long *ap));
  217. LOCAL    int    write_teac_xg1        __PR((SCSI *scgp, caddr_t, long, long, int, BOOL));
  218. LOCAL    int    cdr_write_teac        __PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));
  219. LOCAL    int    open_track_jvc        __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp));
  220. LOCAL    int    teac_fixation        __PR((SCSI *scgp, int onp, int dummy, int toctype, int tracks, track_t *trackp));
  221. LOCAL    int    close_track_teac    __PR((SCSI *scgp, int track, track_t *trackp));
  222. LOCAL    int    teac_open_session    __PR((SCSI *scgp, cdr_t *dp, int tracks, track_t *trackp, int toctype, int multi));
  223. LOCAL    int    teac_init        __PR((SCSI *scgp, int toctype, int multi));
  224. LOCAL    int    teac_doopc        __PR((SCSI *scgp));
  225. LOCAL    int    teac_opc        __PR((SCSI *scgp, caddr_t, int cnt, int doopc));
  226. LOCAL    int    opt_power_judge        __PR((SCSI *scgp, int judge));
  227. LOCAL    int    clear_subcode        __PR((SCSI *scgp));
  228. LOCAL    int    set_limits        __PR((SCSI *scgp, long lba, long length));
  229. LOCAL    int    set_subcode        __PR((SCSI *scgp, u_char *subcode_data, int length));
  230. LOCAL    int    read_disk_info_teac    __PR((SCSI *scgp, u_char *data, int length, int type));
  231. LOCAL    int    teac_freeze        __PR((SCSI *scgp, int bp_flag));
  232. LOCAL    int    teac_wr_pma        __PR((SCSI *scgp));
  233. LOCAL    int    teac_rd_pma        __PR((SCSI *scgp));
  234. LOCAL    int    next_wr_addr_teac    __PR((SCSI *scgp, long start_lba, long last_lba));
  235. LOCAL    int    blank_jvc        __PR((SCSI *scgp, long addr, int blanktype));
  236. LOCAL    int    buf_cap_teac        __PR((SCSI *scgp, long *sp, long *fp));
  237. LOCAL    long    read_peak_buffer_cap_teac __PR((SCSI *scgp));
  238. LOCAL    int    buffer_inquiry_teac    __PR((SCSI *scgp, int fmt));
  239. #ifdef    XXBUFFER
  240. LOCAL    void    check_buffer_teac    __PR((SCSI *scgp));
  241. #endif
  242. #ifdef    XXDEBUG
  243. LOCAL    void    xxtest_teac        __PR((SCSI *scgp));
  244. #endif
  245.  
  246.  
  247. cdr_t    cdr_teac_cdr50 = {
  248.     0,
  249.     CDR_TAO|CDR_DAO|CDR_SWABAUDIO|CDR_NO_LOLIMIT,
  250.     "teac_cdr50",
  251.     "driver for Teac CD-R50S, Teac CD-R55S, JVC XR-W2010, Pinnacle RCD-5020",
  252.     0,
  253.     drive_identify,
  254.     teac_attach,
  255.     teac_getdisktype,
  256.     scsi_load,
  257.     scsi_unload,
  258.     buf_cap_teac,
  259.     (int(*)__PR((SCSI *)))cmd_dummy,    /* recovery_needed    */
  260.     (int(*)__PR((SCSI *, int)))cmd_dummy,    /* recover        */
  261.     speed_select_teac,
  262.     select_secsize,
  263.     next_wr_addr_jvc,
  264.     (int(*)__PR((SCSI *, Ulong)))cmd_ill,    /* reserve_track    */
  265.     cdr_write_teac,
  266.     no_sendcue,
  267.     open_track_jvc,
  268.     close_track_teac,
  269.     teac_open_session,
  270.     cmd_dummy,
  271.     read_session_offset_philips,
  272.     teac_fixation,
  273. /*    blank_dummy,*/
  274.     blank_jvc,
  275.     teac_opc,
  276. };
  277.  
  278. LOCAL int
  279. teac_getdisktype(scgp, dp, dsp)
  280.     SCSI    *scgp;
  281.     cdr_t    *dp;
  282.     dstat_t    *dsp;
  283. {
  284.     struct scsi_mode_data md;
  285.     int    count = sizeof(struct scsi_mode_header) +
  286.             sizeof(struct scsi_mode_blockdesc);
  287.     int    len;
  288.     int    page = 0;
  289.     long    l;
  290.  
  291.     fillbytes((caddr_t)&md, sizeof(md), '\0');
  292.  
  293.     (void)test_unit_ready(scgp);
  294.     if (mode_sense(scgp, (u_char *)&md, count, page, 0) < 0) {    /* Page n current */
  295.         return (-1);
  296.     } else {
  297.         len = ((struct scsi_mode_header *)&md)->sense_data_len + 1;
  298.     }
  299.     if (((struct scsi_mode_header *)&md)->blockdesc_len < 8)
  300.         return (-1);
  301.  
  302.     l = a_to_u_3_byte(md.blockdesc.nlblock);
  303.     dsp->ds_maxblocks = l;
  304.     return (0);
  305. }
  306.  
  307. LOCAL int
  308. speed_select_teac(scgp, speedp, dummy)
  309.     SCSI    *scgp;
  310.     int    *speedp;
  311.     int    dummy;
  312. {
  313.     struct cdd_52x_mode_data md;
  314.     int    count;
  315.     int    status;
  316.     int    speed = 1;
  317.  
  318.     if (speedp)
  319.         speed = *speedp;
  320.  
  321.     fillbytes((caddr_t)&md, sizeof(md), '\0');
  322.  
  323.     count  = sizeof(struct scsi_mode_header) +
  324.         sizeof(struct teac_mode_page_21);
  325.  
  326.     md.pagex.teac_page21.p_code = 0x21;
  327.     md.pagex.teac_page21.p_len =  0x01;
  328.     md.pagex.teac_page21.dummy = dummy?3:0;
  329.  
  330.     status = mode_select(scgp, (u_char *)&md, count, 0, scgp->inq->data_format >= 2);
  331.     if (status < 0)
  332.         return (status);
  333.  
  334.     if (speedp == 0)
  335.         return (0);
  336.  
  337.     fillbytes((caddr_t)&md, sizeof(md), '\0');
  338.  
  339.     count  = sizeof(struct scsi_mode_header) +
  340.         sizeof(struct teac_mode_page_31);
  341.  
  342.     speed >>= 1;
  343.     md.pagex.teac_page31.p_code = 0x31;
  344.     md.pagex.teac_page31.p_len =  0x02;
  345.     md.pagex.teac_page31.speed = speed;
  346.  
  347.     return (mode_select(scgp, (u_char *)&md, count, 0, scgp->inq->data_format >= 2));
  348. }
  349.  
  350. LOCAL int
  351. select_secsize_teac(scgp, trackp)
  352.     SCSI    *scgp;
  353.     track_t    *trackp;
  354. {
  355.     struct scsi_mode_data md;
  356.     int    count = sizeof(struct scsi_mode_header) +
  357.             sizeof(struct scsi_mode_blockdesc);
  358.     int    len;
  359.     int    page = 0;
  360.  
  361.     fillbytes((caddr_t)&md, sizeof(md), '\0');
  362.  
  363.     (void)test_unit_ready(scgp);
  364.     if (mode_sense(scgp, (u_char *)&md, count, page, 0) < 0) {    /* Page n current */
  365.         return (-1);
  366.     } else {
  367.         len = ((struct scsi_mode_header *)&md)->sense_data_len + 1;
  368.     }
  369.     if (((struct scsi_mode_header *)&md)->blockdesc_len < 8)
  370.         return (-1);
  371.  
  372.     md.header.sense_data_len = 0;
  373.     md.header.blockdesc_len = 8;
  374.  
  375.     md.blockdesc.density = 1;
  376.     if (trackp->secsize == 2352)
  377.         md.blockdesc.density = 4;
  378.     i_to_3_byte(md.blockdesc.lblen, trackp->secsize);
  379.     
  380.     return (mode_select(scgp, (u_char *)&md, count, 0, scgp->inq->data_format >= 2));
  381. }
  382.  
  383. LOCAL int
  384. next_wr_addr_jvc(scgp, track, trackp, ap)
  385.     SCSI    *scgp;
  386.     int    track;
  387.     track_t    *trackp;
  388.     long    *ap;
  389. {
  390.     if (track > 0) {
  391.         *ap = lba_addr;
  392.     } else {
  393.         long    nwa;
  394.  
  395.         if (read_B0(scgp, TRUE, &nwa, NULL) < 0)
  396.             return (-1);
  397.  
  398.         *ap = nwa + 150;
  399.     }
  400.     return (0);
  401. }
  402.  
  403. LOCAL int
  404. write_teac_xg1(scgp, bp, sectaddr, size, blocks, extwr)
  405.     SCSI    *scgp;
  406.     caddr_t    bp;        /* address of buffer */
  407.     long    sectaddr;    /* disk address (sector) to put */
  408.     long    size;        /* number of bytes to transfer */
  409.     int    blocks;        /* sector count */
  410.     BOOL    extwr;        /* is an extended write */
  411. {
  412.     register struct    scg_cmd    *scmd = scgp->scmd;
  413.  
  414.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  415.     scmd->addr = bp;
  416.     scmd->size = size;
  417.     scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
  418. /*    scmd->flags = SCG_DISRE_ENA;*/
  419.     scmd->cdb_len = SC_G1_CDBLEN;
  420.     scmd->sense_len = CCS_SENSE_LEN;
  421.     scmd->target = scgp->target;
  422.     scmd->cdb.g1_cdb.cmd = SC_EWRITE;
  423.     scmd->cdb.g1_cdb.lun = scgp->lun;
  424.     g1_cdbaddr(&scmd->cdb.g1_cdb, sectaddr);
  425.     g1_cdblen(&scmd->cdb.g1_cdb, blocks);
  426.     scmd->cdb.g1_cdb.vu_97 = extwr;
  427.  
  428.     scgp->cmdname = "write_teac_g1";
  429.  
  430.     if (scg_cmd(scgp) < 0)
  431.         return (-1);
  432.     return (size - scg_getresid(scgp));
  433. }
  434.  
  435. LOCAL int
  436. cdr_write_teac(scgp, bp, sectaddr, size, blocks, islast)
  437.     SCSI    *scgp;
  438.     caddr_t    bp;        /* address of buffer */
  439.     long    sectaddr;    /* disk address (sector) to put */
  440.     long    size;        /* number of bytes to transfer */
  441.     int    blocks;        /* sector count */
  442.     BOOL    islast;        /* last write for track */
  443. {
  444.     int    ret;
  445.  
  446.     if (islast)
  447.         last_done = TRUE;
  448.  
  449.     ret = write_teac_xg1(scgp, bp, sectaddr, size, blocks, !islast);
  450.     if (ret < 0)
  451.         return (ret);
  452.  
  453.     lba_addr = sectaddr + blocks;
  454. #ifdef    XXBUFFER
  455.     check_buffer_teac(scgp);
  456. #endif
  457.     return (ret);
  458. }
  459.  
  460. LOCAL int
  461. open_track_jvc(scgp, dp, track, trackp)
  462.     SCSI    *scgp;
  463.     cdr_t    *dp;
  464.     int    track;
  465.     track_t    *trackp;
  466. {
  467.     int    status;
  468.     long    blocks;
  469.     long    pregapsize;
  470.     struct    pgm_subcode    sc;
  471.  
  472.     last_done = FALSE;
  473.  
  474.     if (select_secsize_teac(scgp, trackp) < 0)
  475.         return (-1);
  476.  
  477.     status = clear_subcode(scgp);
  478. /*next_wr_addr_teac(scgp);*/
  479.     if (status < 0)
  480.         return (status);
  481.  
  482. if (trackp->pregapsize != 0) {
  483.     if (lverbose > 1) {
  484.         printf("set_limits(%ld, %ld)-> %ld\n",
  485.         lba_addr, trackp->pregapsize, lba_addr + trackp->pregapsize);
  486.     }
  487.  
  488.     status = set_limits(scgp, lba_addr, trackp->pregapsize);
  489.     if (status < 0)
  490.         return (status);
  491.  
  492.     /*
  493.      * Set pre-gap (pause - index 0)
  494.      */
  495.     set_pgm_subcode(&sc, SC_P,
  496.             st2mode[trackp->sectype&ST_MASK], ADR_POS, track, 0);
  497.  
  498.     if (lverbose > 1)
  499.         scg_prbytes("Subcode:", (u_char *)&sc, sizeof(sc));
  500.  
  501.     status = set_subcode(scgp, (u_char *)&sc, sizeof(sc));
  502.     if (status < 0)
  503.         return (status);
  504.  
  505.     pregapsize = trackp->pregapsize;
  506.     if (!is_audio(trackp)) {
  507.         lba_addr += 5;    /* link & run in blocks */
  508.         pregapsize -= 5;
  509.     }
  510.     if (lverbose > 1) {
  511.         printf("pad_track(%ld, %ld)-> %ld\n",
  512.             lba_addr, pregapsize, lba_addr + pregapsize);
  513.     }
  514.     if (pad_track(scgp, dp, track, trackp,
  515.             lba_addr, pregapsize*trackp->secsize,
  516.             FALSE, (long *)0) < 0)
  517.         return (-1);
  518. }
  519.  
  520.     blocks = trackp->tracksize/trackp->secsize +
  521.          (trackp->tracksize%trackp->secsize?1:0);
  522.     blocks += trackp->padsize/trackp->secsize +
  523.          (trackp->padsize%trackp->secsize?1:0);
  524.     if (blocks < 300)
  525.         blocks = 300;
  526.     if (!is_audio(trackp))
  527.         blocks += 2;
  528. if (!is_last(trackp) && trackp[1].pregapsize == 0)
  529.         blocks -= 150;
  530.  
  531.     /*
  532.      * set the limits for the new subcode - seems to apply to all
  533.      * of the data track.
  534.      * Unknown tracksize is handled in open_session.
  535.      * We definitely need to know the tracksize in this driver.
  536.      */
  537.     if (lverbose > 1) {
  538.         printf("set_limits(%ld, %ld)-> %ld\n",
  539.             lba_addr, blocks, lba_addr + blocks);
  540.     }
  541.     status = set_limits(scgp, lba_addr, blocks);
  542.     if (status < 0)
  543.         return (status);
  544.  
  545.     /*
  546.      * Set track start (index 1)
  547.      */
  548.     set_pgm_subcode(&sc, SC_TR,
  549.             st2mode[trackp->sectype&ST_MASK], ADR_POS, track, 1);
  550.  
  551.     if (lverbose > 1)
  552.         scg_prbytes("Subcode:", (u_char *)&sc, sizeof(sc));
  553.  
  554.     status = set_subcode(scgp, (u_char *)&sc, sizeof(sc));
  555.     if (status < 0)
  556.         return (status);
  557.  
  558. if (!is_last(trackp) && trackp[1].pregapsize == 0) {
  559.     blocks += lba_addr;
  560.     pregapsize = 150;
  561.  
  562.     if (lverbose > 1) {
  563.         printf("set_limits(%ld, %ld)-> %ld\n",
  564.         blocks, pregapsize, blocks + pregapsize);
  565.     }
  566.  
  567.     status = set_limits(scgp, blocks, pregapsize);
  568.     if (status < 0)
  569.         return (status);
  570.  
  571.     /*
  572.      * Set pre-gap (pause - index 0)
  573.      */
  574.     track++;
  575.     trackp++;
  576.     set_pgm_subcode(&sc, SC_P,
  577.             st2mode[trackp->sectype&ST_MASK], ADR_POS, track, 0);
  578.  
  579.     if (lverbose > 1)
  580.         scg_prbytes("Subcode:", (u_char *)&sc, sizeof(sc));
  581.  
  582.     status = set_subcode(scgp, (u_char *)&sc, sizeof(sc));
  583.     if (status < 0)
  584.         return (status);
  585. }
  586.     return (status);
  587. }
  588.  
  589. LOCAL    char    sector[3000];
  590.  
  591. LOCAL int
  592. close_track_teac(scgp, track, trackp)
  593.     SCSI    *scgp;
  594.     int    track;
  595.     track_t    *trackp;
  596. {
  597.     int    ret = 0;
  598.  
  599.     if (!last_done) {
  600.         printf("WARNING: adding dummy block to close track.\n");
  601.         /*
  602.          * need read sector size
  603.          * XXX do we really need this ?
  604.          * XXX if we need this can we set blocks to 0 ?
  605.          */
  606.         ret =  write_teac_xg1(scgp, sector, lba_addr, 2352, 1, FALSE);
  607.         lba_addr++;
  608.     }
  609.     if (!is_audio(trackp))
  610.         lba_addr += 2;
  611.     teac_wr_pma(scgp);
  612.     return (ret);
  613. }
  614.  
  615.  
  616.  
  617. static const char *sd_teac50_error_str[] = {
  618.     "\100\200diagnostic failure on component parts",    /* 40 80 */
  619.     "\100\201diagnostic failure on memories",        /* 40 81 */
  620.     "\100\202diagnostic failure on cd-rom ecc circuit",    /* 40 82 */
  621.     "\100\203diagnostic failure on gate array",        /* 40 83 */
  622.     "\100\204diagnostic failure on internal SCSI controller",    /* 40 84 */
  623.     "\100\205diagnostic failure on servo processor",    /* 40 85 */
  624.     "\100\206diagnostic failure on program rom",        /* 40 86 */
  625.     "\100\220thermal sensor failure",            /* 40 90 */
  626.     "\200\000controller prom error",            /* 80 00 */    /* JVC */
  627.     "\201\000no disk present - couldn't get focus",        /* 81 00 */    /* JVC */
  628.     "\202\000no cartridge present",                /* 82 00 */    /* JVC */
  629.     "\203\000unable to spin up",                /* 83 00 */    /* JVC */
  630.     "\204\000addr exceeded the last valid block addr",    /* 84 00 */    /* JVC */
  631.     "\205\000sync error",                    /* 85 00 */    /* JVC */
  632.     "\206\000address can't find or not data track",        /* 86 00 */    /* JVC */
  633.     "\207\000missing track",                /* 87 00 */    /* JVC */
  634.     "\213\000cartridge could not be ejected",        /* 8B 00 */    /* JVC */
  635.     "\215\000audio not playing",                /* 8D 00 */    /* JVC */
  636.     "\216\000read toc error",                /* 8E 00 */    /* JVC */
  637.     "\217\000a blank disk is detected by read toc",        /* 8F 00 */
  638.     "\220\000pma less disk - not a recordable disk",    /* 90 00 */
  639.     "\223\000mount error",                    /* 93 00 */    /* JVC */
  640.     "\224\000toc less disk",                /* 94 00 */
  641.     "\225\000disc information less disk",            /* 95 00 */    /* JVC */
  642.     "\226\000disc information read error",            /* 96 00 */    /* JVC */
  643.     "\227\000linear velocity measurement error",        /* 97 00 */    /* JVC */
  644.     "\230\000drive sequence stop",                /* 98 00 */    /* JVC */
  645.     "\231\000actuator velocity control error",        /* 99 00 */    /* JVC */
  646.     "\232\000slider velocity control error",        /* 9A 00 */    /* JVC */
  647.     "\233\000opc initialize error",                /* 9B 00 */
  648.     "\233\001power calibration not executed",        /* 9B 01 */
  649.     "\234\000opc execution eror",                /* 9C 00 */
  650.     "\234\001alpc error - opc execution",            /* 9C 01 */
  651.     "\234\002opc execution timeout",            /* 9C 02 */
  652.     "\245\000disk application code does not match host application code",    /* A5 00 */
  653.     "\255\000completed preview write",            /* AD 00 */
  654.     "\256\000invalid B0 value",                /* AE 00 */    /* JVC */
  655.     "\257\000pca area full",                /* AF 00 */
  656.     "\260\000efm isn't detected",                /* B0 00 */    /* JVC */
  657.     "\263\000no logical sector",                /* B3 00 */    /* JVC */
  658.     "\264\000full pma area",                /* B4 00 */
  659.     "\265\000read address is atip area - blank",        /* B5 00 */
  660.     "\266\000write address is efm area - aleady written",    /* B6 00 */
  661.     "\271\000abnormal spinning - servo irq",        /* B9 00 */    /* JVC */
  662.     "\272\000no write data - buffer empty",            /* BA 00 */
  663.     "\273\000write emergency occurred",            /* BB 00 */
  664.     "\274\000read timeout",                    /* BC 00 */    /* JVC */
  665.     "\277\000abnormal spin - nmi",                /* BF 00 */    /* JVC */
  666.     "\301\0004th run-in block detected",            /* C1 00 */
  667.     "\302\0003rd run-in block detected",            /* C2 00 */
  668.     "\303\0002nd run-in block detected",            /* C3 00 */
  669.     "\304\0001st run-in block detected",            /* C4 00 */
  670.     "\305\000link block detected",                /* C5 00 */
  671.     "\306\0001st run-out block detected",            /* C6 00 */
  672.     "\307\0002nd run-out block detected",            /* C7 00 */
  673.     "\314\000write request means mixed data mode",        /* CC 00 */
  674.     "\315\000unable to ensure reliable writing with the inserted disk - unsupported disk",    /* CD 00 */
  675.     "\316\000unable to ensure reliable writing as the inserted disk does not support speed",/* CE 00 */
  676.     "\317\000unable to ensure reliable writing as the inserted disk has no char id code",    /* CF 00 */
  677.     NULL
  678. };
  679.  
  680. LOCAL int
  681. teac_attach(scgp, dp)
  682.     SCSI    *scgp;
  683.     cdr_t    *dp;
  684. {
  685.     scg_setnonstderrs(scgp, sd_teac50_error_str);
  686. #ifdef    XXDEBUG
  687.     xxtest_teac(scgp);
  688.     exit(0);
  689. #endif
  690.     return (0);
  691. }
  692.  
  693. LOCAL int
  694. teac_fixation(scgp, onp, dummy, toctype, tracks, trackp)
  695.     SCSI    *scgp;
  696.     int    onp;
  697.     int    dummy;
  698.     int    toctype;
  699.     int    tracks;
  700.     track_t    *trackp;
  701. {
  702.     long    lba;
  703.     int    status;
  704.     u_char    *sp;
  705.     int    i;
  706. extern    char    *buf;
  707.  
  708.     if (tracks < 1) {
  709.         /*
  710.          * We come here if cdrecord isonly called with the -fix option.
  711.          * As long as we cannot read and interpret the PMA, we must
  712.          * abort here.
  713.          */
  714.         teac_rd_pma(scgp);
  715. /*        errmsgno(EX_BAD, "Cannot fixate zero track disk.\n");;*/
  716.         errmsgno(EX_BAD, "Cannot fixate without track list (not yet implemented).\n");;
  717.         return (-1);
  718.     }
  719.     sp = (u_char *)buf;
  720.  
  721.     sleep(1);
  722.  
  723.     status = clear_subcode(scgp);
  724.     sleep(1);
  725.     if (status < 0)
  726.         return (status);
  727.  
  728.     sp[0] = 0;        /* reserved */
  729.     sp[1] = 0;        /* reserved */
  730.     sp[2] = 0;        /* Q TNO */
  731.  
  732.     sp = &sp[3];        /* point past header */
  733.  
  734.     /*
  735.      * Set up TOC entries for all tracks
  736.      */
  737.     for(i=1; i <= tracks; i++) {
  738.         lba = trackp[i].trackstart+150;    /* MSF=00:02:00 is LBA=0 */
  739.  
  740.         sp = set_toc_subcode(sp,
  741.                 /* ctrl/adr for this track */
  742.                 st2mode[trackp[i].sectype&ST_MASK], ADR_POS,
  743.                     trackp[i].trackno, lba);
  744.     }
  745.  
  746.     /*
  747.      * Set first track on disk
  748.      *
  749.      * XXX We set the track type for the lead-in to the track type
  750.      * XXX of the first track. The TEAC manual states that we should use
  751.      * XXX audio if the disk contains both, audio and data tracks.
  752.      */
  753.     sp = set_lin_subcode(sp,
  754.         /* ctrl/adr for first track */
  755.         st2mode[trackp[1].sectype&ST_MASK], ADR_POS,
  756.         0xA0,                /* Point A0 */
  757.         trackp[1].trackno,        /* first track # */
  758.         toc2sess[toctype & TOC_MASK],    /* disk type */
  759.         0);                /* reserved */
  760.  
  761.     /*
  762.      * Set last track on disk
  763.      */
  764.     sp = set_lin_subcode(sp,
  765.         /* ctrl/adr for first track */
  766.         st2mode[trackp[1].sectype&ST_MASK], ADR_POS,
  767.         0xA1,                /* Point A1 */
  768.         MSF_CONV(trackp[tracks].trackno),/* last track # */
  769.         0,                /* reserved */
  770.         0);                /* reserved */
  771.  
  772.     /*
  773.      * Set start of lead out area in MSF
  774.      * MSF=00:02:00 is LBA=0
  775.      */
  776.     lba = lba_addr + 150;
  777.     if (lverbose > 1)
  778.     printf("lba: %ld lba_addr: %ld\n", lba, lba_addr);
  779.  
  780.     if (lverbose > 1)
  781.     printf("Lead out start: (%02d:%02d/%02d)\n",
  782.             minutes(lba*2352),
  783.             seconds(lba*2352),
  784.             frames(lba*2352));
  785.  
  786.     sp = set_lin_subcode(sp,
  787.         /* ctrl/adr for first track */
  788.         st2mode[trackp[1].sectype&ST_MASK], ADR_POS,
  789.         0xA2,                /* Point A2 */
  790.         MSF_CONV(LBA_MIN(lba)),
  791.         MSF_CONV(LBA_SEC(lba)),
  792.         MSF_CONV(LBA_FRM(lba)));
  793.  
  794.     status = sp - ((u_char *)buf);
  795.     if (lverbose > 1) {
  796.         printf("Subcode len: %d\n", status);
  797.         scg_prbytes("Subcode:", (u_char *)buf, status);
  798.     }
  799.     status = set_subcode(scgp, (u_char *)buf, status);
  800.     sleep(1);
  801.     if (status < 0)
  802.         return (status);
  803.  
  804.     /*
  805.      * now write the toc
  806.      */
  807.     status = teac_freeze(scgp, !onp);
  808.     return (status);
  809.  
  810. }
  811.  
  812. LOCAL int
  813. teac_open_session(scgp, dp, tracks, trackp, toctype, multi)
  814.     SCSI    *scgp;
  815.     cdr_t    *dp;
  816.     int    tracks;
  817.     track_t    *trackp;
  818.     int    toctype;
  819.     int    multi;
  820. {
  821.     int    i;
  822.  
  823.     for (i = 1; i <= tracks; i++) {
  824.         if (trackp[i].tracksize < 0) {
  825.             /*
  826.              * XXX How about setting the subcode range to infinity.
  827.              * XXX and correct it in clode track before writing
  828.              * XXX the PMA?
  829.              */
  830.             errmsgno(EX_BAD, "Track %d has unknown length.\n", i);
  831.             return (-1);
  832.         }
  833.     }
  834.     return (teac_init(scgp, toctype, multi));
  835. }
  836.  
  837. LOCAL int
  838. teac_init(scgp, toctype, multi)
  839.     SCSI    *scgp;
  840.     int    toctype;
  841.     int    multi;
  842. {
  843.     int    status;
  844.  
  845.     scgp->silent++;
  846.     if (read_B0(scgp, TRUE, &lba_addr, NULL) < 0)
  847.         lba_addr = -150;
  848.     scgp->silent--;
  849.  
  850.     status = clear_subcode(scgp);
  851.     if (status < 0)
  852.         return (status);
  853.  
  854.     return (0);
  855. }
  856.  
  857. LOCAL int
  858. teac_doopc(scgp)
  859.     SCSI    *scgp;
  860. {
  861.     int    status;
  862.  
  863.     if (lverbose) {
  864.         fprintf(stdout, "Judging disk...");
  865.         flush();
  866.     }
  867.     status = opt_power_judge(scgp, 1);
  868.     if (status < 0) {
  869.         printf("\n");
  870.         return (status);
  871.     }
  872.     if (lverbose) {
  873.         fprintf(stdout, "done.\nCalibrating laser...");
  874.         flush();
  875.     }
  876.  
  877.     status = opt_power_judge(scgp, 0);
  878.     if (lverbose) {
  879.         fprintf(stdout, "done.\n");
  880.     }
  881.     /*
  882.      * Check for error codes 0xCD ... 0xCF
  883.      */
  884.     scgp->silent++;
  885.     if (next_wr_addr_teac(scgp, -1, -1) < 0) {
  886.         if (scgp->verbose == 0 && scg_sense_key(scgp) != SC_ILLEGAL_REQUEST)
  887.             scg_printerr(scgp);
  888.     }
  889.     scgp->silent--;
  890.     return (status);
  891. }
  892.  
  893. LOCAL int
  894. teac_opc(scgp, bp, cnt, doopc)
  895.     SCSI    *scgp;
  896.     caddr_t    bp;
  897.     int    cnt;
  898.     int    doopc;
  899. {
  900.     int    status;
  901.     int    count = 0;
  902.  
  903.     do {
  904.         status = teac_doopc(scgp);
  905.     } while (++count <= 1 && status < 0);
  906.  
  907.     return (status);
  908. }
  909.  
  910. /*--------------------------------------------------------------------------*/
  911. #define SC_SET_LIMITS        0xb3        /* teac 12 byte command */
  912. #define SC_SET_SUBCODE        0xc2        /* teac 10 byte command */
  913. #define SC_READ_PMA        0xc4        /* teac 10 byte command */
  914. #define SC_READ_DISK_INFO    0xc7        /* teac 10 byte command */
  915. #define SC_BUFFER_INQUIRY    0xe0        /* teac 12 byte command */
  916.  
  917. #define SC_WRITE_PMA        0xe1        /* teac 12 byte command */
  918. #define SC_FREEZE        0xe3        /* teac 12 byte command */
  919. #define SC_OPC_EXECUTE        0xec        /* teac 12 byte command */
  920. #define SC_CLEAR_SUBCODE    0xe4        /* teac 12 byte command */
  921. #define SC_NEXT_WR_ADDRESS    0xe6        /* teac 12 byte command */
  922.  
  923. #define SC_READ_PEAK_BUF_CAP    0xef        /* teac 12 byte command */
  924.  
  925. /* -----------------------------------------------------------------
  926.  * Optimum power calibration for Teac Drives.
  927. ----------------------------------------------------------------- */
  928. LOCAL int
  929. opt_power_judge(scgp, judge)
  930.     SCSI    *scgp;
  931.     int    judge;
  932. {
  933.     register struct    scg_cmd    *scmd = scgp->scmd;
  934.  
  935.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  936.     scmd->addr = (caddr_t)0;
  937.     scmd->size = 0;
  938.     scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
  939.     scmd->cdb_len = SC_G5_CDBLEN;
  940.     scmd->sense_len = CCS_SENSE_LEN;
  941.     scmd->target = scgp->target;
  942.     scmd->timeout = 60;
  943.  
  944.     scmd->cdb.g5_cdb.cmd = SC_OPC_EXECUTE;
  945.     scmd->cdb.g5_cdb.lun = scgp->lun;
  946.     scmd->cdb.g5_cdb.reladr = judge; /* Judge the Disc */
  947.  
  948.     scgp->cmdname = "opt_power_judge";
  949.  
  950.     return (scg_cmd(scgp));
  951. }
  952.  
  953. /* -----------------------------------------------------------------
  954.  * Clear subcodes for Teac Drives.
  955. ----------------------------------------------------------------- */
  956. LOCAL int
  957. clear_subcode(scgp)
  958.     SCSI    *scgp;
  959. {
  960.     register struct    scg_cmd    *scmd = scgp->scmd;
  961.  
  962.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  963.     scmd->addr = (caddr_t)0;
  964.     scmd->size = 0;
  965.     scmd->flags = SCG_DISRE_ENA;
  966.     scmd->cdb_len = SC_G5_CDBLEN;
  967.     scmd->sense_len = CCS_SENSE_LEN;
  968.     scmd->target = scgp->target;
  969.  
  970.     scmd->cdb.g5_cdb.cmd = SC_CLEAR_SUBCODE;
  971.     scmd->cdb.g5_cdb.lun = scgp->lun;
  972.     scmd->cdb.g5_cdb.addr[3] = 0x80;
  973.  
  974.     scgp->cmdname = "clear subcode";
  975.  
  976.     return (scg_cmd(scgp));
  977. }
  978.  
  979. /* -----------------------------------------------------------------
  980.  * Set limits for command linking for Teac Drives.
  981. ----------------------------------------------------------------- */
  982. LOCAL int
  983. set_limits(scgp, lba, length)
  984.     SCSI    *scgp;
  985.     long    lba;
  986.     long    length;
  987. {
  988.     register struct    scg_cmd    *scmd = scgp->scmd;
  989.  
  990.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  991.     scmd->addr = (caddr_t)0;
  992.     scmd->size = 0;
  993.     scmd->flags = SCG_DISRE_ENA;
  994.     scmd->cdb_len = SC_G5_CDBLEN;
  995.     scmd->sense_len = CCS_SENSE_LEN;
  996.     scmd->target = scgp->target;
  997.  
  998.     scmd->cdb.g5_cdb.cmd = SC_SET_LIMITS;
  999.     scmd->cdb.g5_cdb.lun = scgp->lun;
  1000.     i_to_4_byte(&scmd->cdb.g5_cdb.addr[0], lba);
  1001.     i_to_4_byte(&scmd->cdb.g5_cdb.count[0], length);
  1002.  
  1003.     scgp->cmdname = "set limits";
  1004.  
  1005.     return (scg_cmd(scgp));
  1006. }
  1007.  
  1008. /* -----------------------------------------------------------------
  1009.  * Set subcode for Teac Drives.
  1010. ----------------------------------------------------------------- */
  1011. LOCAL int
  1012. set_subcode(scgp, subcode_data, length)
  1013.     SCSI    *scgp;
  1014.     u_char    *subcode_data;
  1015.     int    length;
  1016. {
  1017.     register struct    scg_cmd    *scmd = scgp->scmd;
  1018.  
  1019.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1020.     scmd->addr = (caddr_t)subcode_data;
  1021.     scmd->size = length;
  1022.     scmd->flags = SCG_DISRE_ENA;
  1023.     scmd->cdb_len = SC_G1_CDBLEN;
  1024.     scmd->sense_len = CCS_SENSE_LEN;
  1025.     scmd->target = scgp->target;
  1026.  
  1027.     scmd->cdb.g1_cdb.cmd = SC_SET_SUBCODE;
  1028.     scmd->cdb.g1_cdb.lun = scgp->lun;
  1029.     g1_cdblen(&scmd->cdb.g1_cdb, length);
  1030.  
  1031.     scgp->cmdname = "set subcode";
  1032.  
  1033.     return (scg_cmd(scgp));
  1034. }
  1035.  
  1036. LOCAL int
  1037. read_disk_info_teac(scgp, data, length, type)
  1038.     SCSI    *scgp;
  1039.     u_char    *data;
  1040.     int    length;
  1041.     int    type;
  1042. {
  1043.     register struct    scg_cmd    *scmd = scgp->scmd;
  1044.  
  1045.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1046.     scmd->addr = (caddr_t)data;
  1047.     scmd->size = length;
  1048.     scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1049.     scmd->cdb_len = SC_G1_CDBLEN;
  1050.     scmd->sense_len = CCS_SENSE_LEN;
  1051.     scmd->target = scgp->target;
  1052.  
  1053.     scmd->cdb.g1_cdb.cmd = SC_READ_DISK_INFO;
  1054.     scmd->cdb.g1_cdb.lun = scgp->lun;
  1055.  
  1056.     scmd->cdb.g1_cdb.reladr = type & 1;
  1057.     scmd->cdb.g1_cdb.res    = (type & 2) >> 1;
  1058.  
  1059.     scgp->cmdname = "read disk info teac";
  1060.  
  1061.     return (scg_cmd(scgp));
  1062. }
  1063.  
  1064. /* -----------------------------------------------------------------
  1065.  * Perform the freeze command for Teac Drives.
  1066. ----------------------------------------------------------------- */
  1067. LOCAL int
  1068. teac_freeze(scgp, bp_flag)
  1069.     SCSI    *scgp;
  1070.     int    bp_flag;
  1071. {
  1072.     register struct    scg_cmd    *scmd = scgp->scmd;
  1073.  
  1074.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1075.     scmd->addr = (caddr_t)0;
  1076.     scmd->size = 0;
  1077.     scmd->flags = SCG_DISRE_ENA;
  1078.     scmd->cdb_len = SC_G5_CDBLEN;
  1079.     scmd->sense_len = CCS_SENSE_LEN;
  1080.     scmd->target = scgp->target;
  1081.     scmd->timeout = 8 * 60;        /* Needs up to 4 minutes */
  1082.  
  1083.     scmd->cdb.g5_cdb.cmd = SC_FREEZE;
  1084.     scmd->cdb.g5_cdb.lun = scgp->lun;
  1085.     scmd->cdb.g5_cdb.addr[3] = bp_flag ? 0x80 : 0;
  1086.  
  1087.     scgp->cmdname = "teac_freeze";
  1088.  
  1089.     return (scg_cmd(scgp));
  1090. }
  1091.  
  1092. LOCAL int
  1093. teac_wr_pma(scgp)
  1094.     SCSI    *scgp;
  1095. {
  1096.     register struct    scg_cmd    *scmd = scgp->scmd;
  1097.  
  1098.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1099.     scmd->addr = (caddr_t)0;
  1100.     scmd->size = 0;
  1101.     scmd->flags = SCG_DISRE_ENA;
  1102.     scmd->cdb_len = SC_G5_CDBLEN;
  1103.     scmd->sense_len = CCS_SENSE_LEN;
  1104.     scmd->target = scgp->target;
  1105.  
  1106.     scmd->cdb.g5_cdb.cmd = SC_WRITE_PMA;
  1107.     scmd->cdb.g5_cdb.lun = scgp->lun;
  1108.  
  1109.     scgp->cmdname = "teac_write_pma";
  1110.  
  1111.     return (scg_cmd(scgp));
  1112. }
  1113.  
  1114. /* -----------------------------------------------------------------
  1115.  * Read PMA for Teac Drives.
  1116. ----------------------------------------------------------------- */
  1117. LOCAL int
  1118. teac_rd_pma(scgp)
  1119.     SCSI    *scgp;
  1120. {
  1121.     unsigned char    xx[256];
  1122.     register struct    scg_cmd    *scmd = scgp->scmd;
  1123.  
  1124.     fillbytes((caddr_t)xx, sizeof(xx), '\0');
  1125.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1126.     scmd->addr = (caddr_t)xx;
  1127.     scmd->size = sizeof(xx);
  1128.     scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1129.     scmd->cdb_len = SC_G1_CDBLEN;
  1130.     scmd->sense_len = CCS_SENSE_LEN;
  1131.     scmd->target = scgp->target;
  1132.  
  1133.     scmd->cdb.g1_cdb.cmd = SC_READ_PMA;
  1134.     scmd->cdb.g1_cdb.lun = scgp->lun;
  1135.  
  1136.     g1_cdblen(&scmd->cdb.g1_cdb, sizeof(xx));
  1137.  
  1138.     scgp->cmdname = "teac_read_pma";
  1139.  
  1140. /*    return (scg_cmd(scgp));*/
  1141.     if (scg_cmd(scgp) < 0)
  1142.         return (-1);
  1143.  
  1144.     if (scgp->verbose) {
  1145.         scg_prbytes("PMA Data", xx, sizeof(xx) - scg_getresid(scgp));
  1146.     }
  1147.     if (lverbose) {
  1148.         unsigned i;
  1149.         Uchar    *p;
  1150.  
  1151.         scg_prbytes("PMA Header: ", xx, 4);
  1152.         i = xx[2];
  1153.         p = &xx[4];
  1154.         for (; i <= xx[3]; i++) {
  1155.             scg_prbytes("PMA: ", p, 10);
  1156.             p += 10;
  1157.         }
  1158.     }
  1159.     return (0);
  1160. }
  1161.  
  1162. /* -----------------------------------------------------------------
  1163.  * Next writable address for Teac Drives.
  1164. ----------------------------------------------------------------- */
  1165. LOCAL int
  1166. next_wr_addr_teac(scgp, start_lba, last_lba)
  1167.     SCSI    *scgp;
  1168.     long    start_lba;
  1169.     long    last_lba;
  1170. {
  1171.     unsigned char    xx[256];
  1172.     register struct    scg_cmd    *scmd = scgp->scmd;
  1173.  
  1174.     fillbytes((caddr_t)xx, sizeof(xx), '\0');
  1175.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1176.     scmd->addr = (caddr_t)xx;
  1177.     scmd->size = sizeof(xx);
  1178.     scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1179.     scmd->cdb_len = SC_G5_CDBLEN;
  1180.     scmd->sense_len = CCS_SENSE_LEN;
  1181.     scmd->target = scgp->target;
  1182.  
  1183.     scmd->cdb.g5_cdb.cmd = SC_NEXT_WR_ADDRESS;
  1184.     scmd->cdb.g5_cdb.lun = scgp->lun;
  1185.  
  1186.     i_to_4_byte(&scmd->cdb.g5_cdb.addr[0], start_lba);
  1187.     i_to_4_byte(&scmd->cdb.g5_cdb.count[0], last_lba);
  1188.  
  1189.     if (scgp->verbose)
  1190.         printf("start lba: %ld last lba: %ld\n",
  1191.                     start_lba, last_lba);
  1192.  
  1193.     scgp->cmdname = "next writable address";
  1194.  
  1195. /*    return (scg_cmd(scgp));*/
  1196.     if (scg_cmd(scgp) < 0)
  1197.         return (-1);
  1198.  
  1199.     if (scgp->verbose) {
  1200.         scg_prbytes("WRa Data", xx, sizeof(xx) - scg_getresid(scgp));
  1201.         printf("NWA: %ld\n", a_to_4_byte(xx));
  1202.     }
  1203.     return (0);
  1204. }
  1205.  
  1206. LOCAL int
  1207. blank_jvc(scgp, addr, blanktype)
  1208.     SCSI    *scgp;
  1209.     long    addr;
  1210.     int    blanktype;
  1211. {
  1212.     extern    char    *blank_types[];
  1213.  
  1214.     if (lverbose) {
  1215.         printf("Blanking %s\n", blank_types[blanktype & 0x07]);
  1216.         flush();
  1217.     }
  1218.  
  1219.     return (scsi_blank(scgp, addr, blanktype, FALSE));
  1220. }
  1221.  
  1222. LOCAL int
  1223. buf_cap_teac(scgp, sp, fp)
  1224.     SCSI    *scgp;
  1225.     long    *sp;    /* Size pointer */
  1226.     long    *fp;    /* Free pointer */
  1227. {
  1228.     Ulong    freespace;
  1229.     Ulong    bufsize;
  1230.     long    ret;
  1231.     int    per;
  1232.  
  1233.     ret = read_peak_buffer_cap_teac(scgp);
  1234.     if (ret < 0)
  1235.         return (-1);
  1236.     bufsize = ret;
  1237.     freespace = 0;
  1238.     if (sp)
  1239.         *sp = bufsize;
  1240.     if (fp)
  1241.         *fp = freespace;
  1242.     
  1243.     if (scgp->verbose || (sp == 0 && fp == 0))
  1244.         printf("BFree: %ld K BSize: %ld K\n", freespace >> 10, bufsize >> 10);
  1245.  
  1246.     if (bufsize == 0)
  1247.         return (0);
  1248.     per = (100 * (bufsize - freespace)) / bufsize;
  1249.     if (per < 0)
  1250.         return (0);
  1251.     if (per > 100)
  1252.         return (100);
  1253.     return (per);
  1254. }
  1255.  
  1256. LOCAL long
  1257. read_peak_buffer_cap_teac(scgp)
  1258.     SCSI    *scgp;
  1259. {
  1260.     Uchar    xx[4];
  1261.     register struct    scg_cmd    *scmd = scgp->scmd;
  1262.  
  1263.     fillbytes((caddr_t)xx, sizeof(xx), '\0');
  1264.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1265.     scmd->addr = (caddr_t)xx;
  1266.     scmd->size = sizeof(xx);
  1267.     scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1268.     scmd->cdb_len = SC_G5_CDBLEN;
  1269.     scmd->sense_len = CCS_SENSE_LEN;
  1270.     scmd->target = scgp->target;
  1271.  
  1272.     scmd->cdb.g5_cdb.cmd = SC_READ_PEAK_BUF_CAP;
  1273.     scmd->cdb.g5_cdb.lun = scgp->lun;
  1274.  
  1275.     scgp->cmdname = "read peak buffer capacity";
  1276.  
  1277. #define    BDEBUG
  1278. #ifndef    BDEBUG
  1279.     return (scg_cmd(scgp));
  1280. #else
  1281.     if (scg_cmd(scgp) < 0)
  1282.         return (-1);
  1283.  
  1284. /*    if (scgp->verbose) {*/
  1285.         scg_prbytes("WRa Data", xx, sizeof(xx) - scg_getresid(scgp));
  1286.         printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));
  1287. /*    }*/
  1288.     return (a_to_u_3_byte(&xx[1]));
  1289. /*    return (0);*/
  1290. #endif
  1291. }
  1292.  
  1293. #define    BI_ONE_BYTE    0xC0
  1294. #define    BI_448_BYTE    0x40
  1295. #define    BI_APP_CODE    0x10
  1296.  
  1297. LOCAL int
  1298. buffer_inquiry_teac(scgp, fmt)
  1299.     SCSI    *scgp;
  1300.     int    fmt;
  1301. {
  1302.     Uchar    xx[448];
  1303.     register struct    scg_cmd    *scmd = scgp->scmd;
  1304.  
  1305.     fillbytes((caddr_t)xx, sizeof(xx), '\0');
  1306.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1307.     scmd->addr = (caddr_t)xx;
  1308.     scmd->size = sizeof(xx);
  1309.     scmd->size = 448;
  1310.     scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1311.     scmd->cdb_len = SC_G5_CDBLEN;
  1312.     scmd->sense_len = CCS_SENSE_LEN;
  1313.     scmd->target = scgp->target;
  1314.  
  1315.     scmd->cdb.g5_cdb.cmd = SC_BUFFER_INQUIRY;
  1316.     scmd->cdb.g5_cdb.lun = scgp->lun;
  1317.  
  1318.     if (fmt > 0) {
  1319.         scmd->cdb.g5_cdb.addr[3] = fmt;
  1320.         if (fmt == BI_ONE_BYTE)
  1321.             scmd->size = 1;
  1322.     } else {
  1323.         scmd->cdb.g5_cdb.addr[3] = BI_448_BYTE;
  1324. /*        scmd->cdb.g5_cdb.addr[3] = BI_APP_CODE;*/
  1325.     }
  1326.  
  1327.     scgp->cmdname = "buffer inquiry";
  1328.  
  1329. #define    BDEBUG
  1330. #ifndef    BDEBUG
  1331.     return (scg_cmd(scgp));
  1332. #else
  1333.     if (scg_cmd(scgp) < 0)
  1334.         return (-1);
  1335.  
  1336. /*    if (scgp->verbose) {*/
  1337. /*        scg_prbytes("WRa Data", xx, sizeof(xx) - scg_getresid(scgp));*/
  1338. /*        scg_prbytes("WRa Data", xx, 1);*/
  1339.  
  1340.         if (fmt > 0) printf("fmt: %X ", fmt);
  1341.         scg_prbytes("WRa Data", xx, 9);
  1342.         printf("%d\n", xx[8] - xx[1]);
  1343. /*        printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));*/
  1344. /*    }*/
  1345.     return (0);
  1346. #endif
  1347. }
  1348.  
  1349. #ifdef    XXBUFFER
  1350. LOCAL void
  1351. check_buffer_teac(scgp)
  1352.     SCSI    *scgp;
  1353. {
  1354.     printf("-------\n");
  1355.     buffer_inquiry_teac(scgp, 0);
  1356. #ifdef    SL
  1357.     usleep(40000);
  1358.     buffer_inquiry_teac(scgp, 0);
  1359. #endif
  1360.     read_peak_buffer_cap_teac(scgp);
  1361. }
  1362. #endif
  1363. /*--------------------------------------------------------------------------*/
  1364. #ifdef    XXDEBUG
  1365. #include "scsimmc.h"
  1366.  
  1367. LOCAL    int    g7_teac            __PR((SCSI *scgp));
  1368. LOCAL    int    g6_teac            __PR((SCSI *scgp));
  1369.  
  1370. LOCAL int
  1371. g7_teac(scgp)
  1372.     SCSI    *scgp;
  1373. {
  1374.     Uchar    xx[2048];
  1375.     register struct    scg_cmd    *scmd = scgp->scmd;
  1376.  
  1377.     fillbytes((caddr_t)xx, sizeof(xx), '\0');
  1378.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1379.     scmd->addr = (caddr_t)xx;
  1380.     scmd->size = sizeof(xx);
  1381.     scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1382.     scmd->cdb_len = SC_G5_CDBLEN;
  1383.     scmd->sense_len = CCS_SENSE_LEN;
  1384.     scmd->target = scgp->target;
  1385.  
  1386.     scmd->cdb.g5_cdb.cmd = 0xDf;
  1387. /*    scmd->cdb.g5_cdb.cmd = 0xE5;*/
  1388.     scmd->cdb.g5_cdb.lun = scgp->lun;
  1389.  
  1390. /*    scmd->cdb.g5_cdb.addr[3] = BI_ONE_BYTE;*/
  1391. /*    scmd->size = 1;*/
  1392.  
  1393. /*    scmd->cdb.g5_cdb.addr[3] = BI_448_BYTE;*/
  1394. /*    scmd->cdb.g5_cdb.addr[3] = BI_APP_CODE;*/
  1395.  
  1396.     scgp->cmdname = "g7 teac";
  1397.  
  1398. /*    return (scg_cmd(scgp));*/
  1399.     if (scg_cmd(scgp) < 0)
  1400.         return (-1);
  1401.  
  1402. /*    if (scgp->verbose) {*/
  1403.         scg_prbytes("WRa Data", xx, sizeof(xx) - scg_getresid(scgp));
  1404. /*        scg_prbytes("WRa Data", xx, 1);*/
  1405. /*        scg_prbytes("WRa Data", xx, 9);*/
  1406. /*printf("%d\n", xx[8] - xx[1]);*/
  1407. /*        printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));*/
  1408. /*    }*/
  1409.     return (0);
  1410. }
  1411.  
  1412. LOCAL int
  1413. g6_teac(scgp)
  1414.     SCSI    *scgp;
  1415. {
  1416.     Uchar    xx[2048];
  1417.     register struct    scg_cmd    *scmd = scgp->scmd;
  1418.  
  1419.     fillbytes((caddr_t)xx, sizeof(xx), '\0');
  1420.     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
  1421.     scmd->addr = (caddr_t)xx;
  1422.     scmd->size = sizeof(xx);
  1423.     scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1424.     scmd->cdb_len = SC_G1_CDBLEN;
  1425.     scmd->sense_len = CCS_SENSE_LEN;
  1426.     scmd->target = scgp->target;
  1427.  
  1428.     scmd->cdb.g1_cdb.cmd = 0xC1;
  1429.     scmd->cdb.g1_cdb.cmd = 0xC3;
  1430.     scmd->cdb.g1_cdb.cmd = 0xC6;
  1431.     scmd->cdb.g1_cdb.cmd = 0xC7;    /* Read TOC */
  1432.     scmd->cdb.g1_cdb.cmd = 0xCe;
  1433.     scmd->cdb.g1_cdb.cmd = 0xCF;
  1434.     scmd->cdb.g1_cdb.cmd = 0xC7;    /* Read TOC */
  1435.     scmd->cdb.g1_cdb.lun = scgp->lun;
  1436.  
  1437.     scgp->cmdname = "g6 teac";
  1438.  
  1439. /*    return (scg_cmd(scgp));*/
  1440.     if (scg_cmd(scgp) < 0)
  1441.         return (-1);
  1442.  
  1443. /*    if (scgp->verbose) {*/
  1444.         scg_prbytes("WRa Data", xx, sizeof(xx) - scg_getresid(scgp));
  1445. /*        scg_prbytes("WRa Data", xx, 1);*/
  1446. /*        scg_prbytes("WRa Data", xx, 9);*/
  1447. /*printf("%d\n", xx[8] - xx[1]);*/
  1448. /*        printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));*/
  1449. /*    }*/
  1450.     return (0);
  1451. }
  1452.  
  1453. LOCAL void
  1454. xxtest_teac(scgp)
  1455.     SCSI    *scgp;
  1456. {
  1457.     read_peak_buffer_cap_teac(scgp);
  1458.  
  1459. /*#define    XDI*/
  1460. #ifdef    XDI
  1461.     {
  1462.         u_char cbuf[512];
  1463.  
  1464. /*        read_disk_info_teac(scgp, data, length, type)*/
  1465. /*        read_disk_info_teac(scgp, cbuf, 512, 2);*/
  1466. /*        read_disk_info_teac(scgp, cbuf, 512, 2);*/
  1467.         read_disk_info_teac(scgp, cbuf, 512, 3);
  1468.         scg_prbytes("DI Data", cbuf, sizeof(cbuf) - scg_getresid(scgp));
  1469.     }
  1470. #endif    /* XDI */
  1471.  
  1472.     buffer_inquiry_teac(scgp, -1);
  1473.  
  1474. /*#define    XBU*/
  1475. #ifdef    XBU
  1476.     {
  1477.         int i;
  1478.  
  1479.         for (i = 0; i < 63; i++) {
  1480.             scgp->silent++;
  1481.             buffer_inquiry_teac(scgp, i<<2);
  1482.             scgp->silent--;
  1483.         }
  1484.     }
  1485. #endif    /* XBU */
  1486.  
  1487. /*    printf("LLLL\n");*/
  1488. /*    g7_teac(scgp);*/
  1489. /*    g6_teac(scgp);*/
  1490. }
  1491. #endif    /* XXDEBUG */
  1492.